package redecolaborativa.server.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import redecolaborativa.server.enums.Ordem;
import redecolaborativa.server.objetos.Item;
import redecolaborativa.server.sistema.Gerenciador;

/**
 * Classe utilitaria para auxiliar na organizacao do sistema.
 * @author Isabelly Rocha, Lilia Samapio e Pedro Adelino.
 */
public class Util implements Serializable {
	private static final long serialVersionUID = 1L;
	
	/**
	 * Ordena uma lista de itens pela reputacao de seus donos.
	 */
	public static void sort(List<Item> lista) {
		Collections.sort(lista, new Comparator<Item>(){@Override public int 
		compare(Item a, Item b) {return a.getDono().compareTo(b.getDono());}});
	}
	
	/**
	 * Ordena uma lista em ordem alfabetica.
	 * @param lista Lista a ser ordenada.
	 * @return A lista de itens ordenada em ordem alfabetica.
	 */
	public static List<String> ordenaAlfabetica(Set<String> lista) {
		List<String> apoio = new ArrayList<String>();
		Iterator<String> it = lista.iterator();
		while (it.hasNext()) {
			String string = it.next();
			apoio.add(string);
		} Collections.sort(apoio);
		return apoio;
	}
	
	/**
	 * Metodo que ordena por ordem crescente
	 * @param lista Lista a ser ordenada
	 * @return A lista ordenada crescentemente
	 */
	public static List<Long> ordenaCrescente(Collection<Long> lista) {
		List<Long> apoio = new ArrayList<Long>();
		Iterator<Long> it = lista.iterator();
		while (it.hasNext()) {
			Long time = it.next();
			apoio.add(time);
		} Collections.sort(apoio);
		Collections.reverse(apoio);
		return apoio;
	}
	
	/**
	 * Ordena a pesquisa por data de criacao na ordem crescente ou na ordem decrescente.
	 * @param Lista dos itens que foram encontrados na pesquisa.
	 * @param Tipo de ordem da pesquisa(Se crescente ou decrescente)
	 * @return A lista dos itens ordenada crescentemente ou decrescentemente;
	 * @throws TipoInvalidoException 
	 */
	public static List<Item> ordenaPesquisaPorData(List<Item> pesquisa, String ordem) throws Exception {
		Collections.sort(pesquisa);
		if (ordem.equalsIgnoreCase(Ordem.CRESCENTE.name())) {
			return pesquisa;
		} else if (ordem.equalsIgnoreCase(Ordem.DECRESCENTE.name())) {
			Collections.reverse(pesquisa);
		} return pesquisa;
	}

	/**
	 * Ordena pesquisa por reputacao do usuario, na ordem crescente ou na ordem decrescente de numeros de emprestimos completados.
	 * @param pesquisa Lista dos itens que foram encontrados na pesquisa
	 * @param ordem Tipo de ordem da pesquisa(Se crescente ou decrescente)
	 * @return A lista dos itens ordenada crescentemente ou decrescentemente
	 * @throws TipoInvalidoException 
	 */
	public static List<Item> ordenaPesquisaPorReputacao(List<Item> pesquisa, String ordem) throws Exception {
		Util.sort(pesquisa);
		if (ordem.equalsIgnoreCase(Ordem.CRESCENTE.name())) {
			return pesquisa;
		} else if (ordem.equalsIgnoreCase(Ordem.DECRESCENTE.name())) {
			Collections.reverse(pesquisa);
		} return pesquisa;
	}
	
	
	/**
	 * Grava o objeto passado no parametro em um arquivo de texto.
	 * @param Objeto a ser gravado no arquivo.
	 */
	public static void gravaDadosEmArquivo(Serializable objeto) {
        try {
        	ObjectOutputStream objGravar = new ObjectOutputStream(new FileOutputStream(new File("dados.txt")));
            objGravar.reset();
        	objGravar.writeObject(objeto);
        	objGravar.flush();
            objGravar.close();
        } catch (Exception ex) {
        	System.err.println(ex.getMessage());
        }
    }
	
	/**
	 * Recupera os dado atuais do arquivo.
	 * @return Dados presentes no arquivo
	 */
    public static Gerenciador recuperaDadosDeArquivo() {
		try {
            ObjectInputStream objLeitura = new ObjectInputStream(new FileInputStream("dados.txt"));
            Object obj = objLeitura.readObject();
            objLeitura.close();
            return (Gerenciador) obj;
        } catch(Exception ex) {
        	return null;
        } 
    }
}